import uuid
from datetime import datetime
from typing import Literal, Optional

from pydantic import Field, field_serializer, field_validator

from src.models.base import IdenticalModel
from src.utils.date_utils import parse_date


class FreshGraduateRecord(IdenticalModel):
    name: str = Field(
        title="姓名",
        min_length=1,
        description="姓名，不允许为空",
        serialization_alias="姓名",
    )
    id: str = Field(
        title="学号",
        min_length=1,
        description="学号，不允许为空",
        serialization_alias="学号",
    )
    education_level: Literal["本科", "硕士", "博士"] = Field(
        title="培养层次",
        default="博士",
        description="培养层次，只能为“本科”、“硕士”或“博士”",
        serialization_alias="培养层次",
    )
    major: str = Field(
        title="专业",
        min_length=1,
        description="专业，不允许为空",
        serialization_alias="专业",
    )
    graduate_at: str = Field(
        title="届别",
        min_length=1,
        description="届别，不允许为空",
        serialization_alias="届别",
    )

    employer: str = Field(
        title="去向单位名称",
        min_length=1,
        description="去向单位名称，不允许为空",
        serialization_alias="去向单位名称",
    )
    employer_address: str = Field(
        title="去向单位地址",
        min_length=1,
        description="去向单位地址，不允许为空",
        serialization_alias="去向单位地址",
    )

    student_origin_address: str = Field(
        title="生源所在地",
        min_length=1,
        description="生源所在地，不允许为空",
        serialization_alias="生源所在地",
    )
    student_id_card_number: str = Field(
        title="身份证号",
        min_length=1,
        description="身份证号，不允许为空",
        serialization_alias="身份证号",
    )
    student_phone_number: str = Field(
        title="联系方式",
        min_length=1,
        description="联系方式，不允许为空",
        serialization_alias="联系方式",
    )

    archives_recv_type: str = Field(
        title="档案转递类型",
        min_length=1,
        description="档案转递类型，不允许为空",
        serialization_alias="档案转递类型",
    )
    archives_recv_number: str = Field(
        title="档案转递编号",
        min_length=1,
        description="档案转递编号，不允许为空",
        serialization_alias="档案转递编号",
    )
    archives_recv_unit_name: str = Field(
        title="档案接收单位",
        min_length=1,
        description="档案接收单位，不允许为空",
        serialization_alias="档案接收单位",
    )
    archives_recv_address: str = Field(
        title="档案接收地址",
        min_length=1,
        description="档案接收地址，不允许为空",
        serialization_alias="档案接收地址",
    )
    archives_recvier: str = Field(
        title="档案接收人",
        min_length=1,
        description="档案接收人，不允许为空",
        serialization_alias="档案接收人",
    )
    archives_recvier_phone_number: str = Field(
        title="档案接收人电话",
        min_length=1,
        description="档案接收人电话，不允许为空",
        serialization_alias="档案接收人电话",
    )
    send_time: datetime = Field(
        title="寄出时间",
        description="格式为YYYY-MM-DD，如果为空则使用当天日期",
        default_factory=datetime.now,
        serialization_alias="寄出时间",
    )
    remark: str = Field(title="备注", default="", serialization_alias="备注")
    # in_print_list: bool = Field(
    #     title="是否在打印列表中",
    #     default=False,
    #     description="是否在打印列表中",
    #     json_schema_extra={"hidden": True, "non_data_field": True, "uneditable": True},
    # )

    @field_serializer("send_time")
    def format_send_time(self, v: datetime):
        return v.strftime("%Y-%m-%d")

    @field_validator("send_time", mode="before")
    def parse_send_time(cls, v):
        if isinstance(v, str):
            dt = parse_date(v)
            if dt is None:
                return datetime.now()
        return v


class FormerGraduateRecord(IdenticalModel):
    name: str = Field(
        title="姓名",
        min_length=1,
        description="姓名，不允许为空",
        serialization_alias="姓名",
    )
    id: str = Field(
        title="学号",
        min_length=1,
        description="学号，不允许为空",
        serialization_alias="学号",
    )
    education_level: Literal["本科", "硕士", "博士"] = Field(
        title="培养层次",
        default="博士",
        description="培养层次，只能为“本科”、“硕士”或“博士”",
        serialization_alias="培养层次",
    )
    major: str = Field(
        title="专业",
        min_length=1,
        description="专业，不允许为空",
        serialization_alias="专业",
    )

    student_id_card_number: str = Field(
        title="身份证号",
        description="身份证号",
        serialization_alias="身份证号",
    )
    student_phone_number: str = Field(
        title="联系方式",
        description="联系方式",
        serialization_alias="联系方式",
    )
    archives_recv_unit_name: str = Field(
        title="档案接收单位",
        min_length=1,
        description="档案接收单位，不允许为空",
        serialization_alias="档案接收单位",
    )
    archives_recv_address: str = Field(
        title="档案接收地址",
        min_length=1,
        description="档案接收地址，不允许为空",
        serialization_alias="档案接收地址",
    )
    archives_recvier: str = Field(
        title="档案接收人",
        min_length=1,
        description="档案接收人，不允许为空",
        serialization_alias="档案接收人",
    )
    archives_recvier_phone_number: str = Field(
        title="档案接收人电话",
        min_length=1,
        description="档案接收人电话，不允许为空",
        serialization_alias="档案接收人电话",
    )

    send_time: datetime = Field(
        title="寄出时间",
        description="格式为YYYY-MM-DD，如果为空则使用当天日期",
        default_factory=datetime.now,
        serialization_alias="寄出时间",
    )
    # in_print_list: bool = Field(
    #     title="是否在打印列表中",
    #     default=False,
    #     description="是否在打印列表中",
    #     json_schema_extra={"hidden": True, "non_data_field": True, "uneditable": True},
    # )
    remark: str = Field(title="备注", default="", serialization_alias="备注")

    @field_serializer("send_time")
    def format_send_time(self, v: datetime):
        return v.strftime("%Y-%m-%d")

    @field_validator("send_time", mode="before")
    def parse_send_time(cls, v):
        if isinstance(v, str):
            dt = parse_date(v)
            if dt is None:
                return datetime.now()
        return v


class HistoryMailRecord(IdenticalModel):
    id: str = Field(
        default_factory=lambda: str(uuid.uuid4()),
        json_schema_extra={"uneditable": True, "hidden": True},
    )
    name: str = Field(
        title="姓名",
        min_length=1,
        description="姓名，不允许为空",
        serialization_alias="姓名",
    )
    stu_id: str = Field(title="学号", serialization_alias="学号")
    major: str = Field(title="专业", serialization_alias="专业")
    graduate_at: str = Field(title="届别", serialization_alias="届别")

    send_time: Optional[datetime] = Field(
        title="寄出时间",
        default=None,
        description="格式为YYYY-MM-DD，可以留空",
        serialization_alias="寄出时间",
    )

    employer: str = Field(title="去向单位名称", serialization_alias="去向单位名称")
    employer_address: str = Field(
        title="去向单位地址", serialization_alias="去向单位地址"
    )

    student_origin_address: str = Field(
        title="生源所在地", serialization_alias="生源所在地"
    )
    student_id_card_number: str = Field(
        title="身份证号", serialization_alias="身份证号"
    )
    student_phone_number: str = Field(title="联系方式", serialization_alias="联系方式")

    archives_recv_type: str = Field(
        title="档案转递类型", serialization_alias="档案转递类型"
    )
    archives_recv_number: str = Field(
        title="档案转递编号", serialization_alias="档案转递编号"
    )
    archives_recv_unit_name: str = Field(
        title="档案接收单位", serialization_alias="档案接收单位"
    )
    archives_recv_address: str = Field(
        title="档案接收地址", serialization_alias="档案接收地址"
    )
    archives_recvier: str = Field(title="档案接收人", serialization_alias="档案接收人")
    archives_recvier_phone_number: str = Field(
        title="档案接收人电话", serialization_alias="档案接收人电话"
    )

    education_level: Literal["本科", "硕士", "博士", ""] = Field(
        title="培养层次", serialization_alias="培养层次"
    )

    archive_delivery_status: Literal["已寄出", "未寄出", ""] = Field(
        title="档案寄出情况",
        default="未寄出",
        description="只能为“已寄出”或“未寄出”或留空",
        serialization_alias="档案寄出情况",
    )
    tracking_number: str = Field(
        title="快递单号/机要号", default="", serialization_alias="快递单号/机要号"
    )
    remark: str = Field(title="备注", default="", serialization_alias="备注")

    @field_serializer("send_time")
    def format_send_time(self, v: Optional[datetime]):
        return v.strftime("%Y-%m-%d") if v is not None else None

    @field_validator("send_time", mode="before")
    def parse_send_time(cls, v):
        if isinstance(v, str):
            return parse_date(v)
        return v

    @classmethod
    def from_former_graduate_record(
        cls, record: FormerGraduateRecord, tracking_number: str
    ):
        return cls(
            name=record.name,
            stu_id=record.id,
            major=record.major,
            graduate_at="",
            send_time=record.send_time,
            employer="",
            employer_address="",
            student_origin_address="",
            student_id_card_number=record.student_id_card_number,
            student_phone_number=record.student_phone_number,
            archives_recv_type="",
            archives_recv_number="",
            archives_recv_unit_name=record.archives_recv_unit_name,
            archives_recv_address=record.archives_recv_address,
            archives_recvier=record.archives_recvier,
            archives_recvier_phone_number=record.archives_recvier_phone_number,
            education_level=record.education_level,
            archive_delivery_status="已寄出",
            tracking_number=tracking_number,
            remark=record.remark,
        )

    @classmethod
    def from_fresh_graduate_record(
        cls, record: FreshGraduateRecord, tracking_number: str
    ):
        return cls(
            name=record.name,
            stu_id=record.id,
            major=record.major,
            graduate_at=record.graduate_at,
            send_time=record.send_time,
            employer=record.employer,
            employer_address=record.employer_address,
            student_origin_address=record.student_origin_address,
            student_id_card_number=record.student_id_card_number,
            student_phone_number=record.student_phone_number,
            archives_recv_type=record.archives_recv_type,
            archives_recv_number=record.archives_recv_number,
            archives_recv_unit_name=record.archives_recv_unit_name,
            archives_recv_address=record.archives_recv_address,
            archives_recvier=record.archives_recvier,
            archives_recvier_phone_number=record.archives_recvier_phone_number,
            education_level=record.education_level,
            archive_delivery_status="已寄出",
            tracking_number=tracking_number,
            remark=record.remark,
        )
